#include "region.hpp"
#include "village.hpp"

#include "helpers.hpp"

int main()
{
    Village a1(0, 1, 1);
    Village a2(1, 2, -2);
    // Village a3(2, -3, 5);

    Region r;
    r.add_village(a1);
    r.add_village(a2);
    r.add_village(2, -3, 5);
    r.add_village(3, 4, 4);
    r.add_village(4, -8, -8);
    r.add_village(5, -5, 12);
    r.add_village(6, 12, -3);
    r.add_village(7, 0, 0);

    // print the Village items in the region
    std::cout << "Original Village data in region:" << std::endl; 

    vector<Village> v_list = r.get_region();
    for (auto it = v_list.begin(); it != v_list.end(); ++it)
    {
        std::cout << "ID: " << it->get_id() << "  "
                  << "x: "  << it->get_x()  << "  "
                  << "y: "  << it->get_y()  << std::endl;
    }

    // set id2 Village to new location (-8, 3)
    r.set_village(2, -8, 3);

    std::cout << "Set Village 2 to new location:" << std::endl; 
    v_list = r.get_region();
    for (auto it = v_list.begin(); it != v_list.end(); ++it)
    {
        std::cout << "ID: " << it->get_id() << "  "
                  << "x: "  << it->get_x()  << "  "
                  << "y: "  << it->get_y()  << std::endl;
    }

    // // delete Village 1
    // r.del_village(1);
    
    // std::cout << "Delete Village 1:" << std::endl; 
    // v_list = r.get_region();
    // for (auto it = v_list.begin(); it != v_list.end(); ++it)
    // {
    //     std::cout << "ID: " << it->get_id() << "  "
    //               << "x: "  << it->get_x()  << "  "
    //               << "y: "  << it->get_y()  << std::endl;
    // }

    MatrixXd m = region_to_mat(r);
    Graph g = matrix_to_graph(m);

    auto edges = primMST(g);
    for (auto ite : edges)
    {
        std::cout << ite.from->value << "->"
                  << ite.to->value   << "  "
                  << "  dist: " << ite.weight
                  << std::endl;
    }

    MatrixXd m_ = unordered_set_to_matrix(edges);
    // std::cout << m_ << std::endl;
    Graph g_ = matrix_to_graph(m_);
    
    auto sp = shortest_path(g_, *g.nodes[7], *g.nodes[6]);

    std::cout << "The shortest path from " 
              << g.nodes[7]->value << " to " << g.nodes[6]->value
              << " is:" << std::endl;
    for (auto &&i : sp)
    {
        std::cout << i.value << "->";
    }
    std::cout << std::endl;
}